package com.imooc.alllearning.controller;

import com.imooc.alllearning.common.PageQuery;
import com.imooc.alllearning.common.PageResult;
import com.imooc.alllearning.common.ResponseResult;
import com.imooc.alllearning.domain.dto.UserDTO;
import com.imooc.alllearning.domain.dto.UserQueryDTO;
import com.imooc.alllearning.domain.entity.UserDO;
import com.imooc.alllearning.domain.vo.UserVO;
import com.imooc.alllearning.exception.ErrorCodeEnum;
import com.imooc.alllearning.service.ExcelExportService;
import com.imooc.alllearning.service.UserService;
import com.imooc.alllearning.util.InsertValidationGroup;
import com.imooc.alllearning.util.UpdateValidationGroup;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created by lijian on 2020/3/27 11:22
 */
@RestController
@RequestMapping("/api/users")
@Validated
@Slf4j
@Api(
        value = "用户管理Controller",
        protocols = "http, https",
        hidden = false
)
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private ExcelExportService excelExportService;

    /**
     * 新建用户
     * POST /api/users UserDTO
     * @param userDTO
     * @return
     */
    @CacheEvict(cacheNames = "users-cache", allEntries = true)
    @PostMapping
    public ResponseResult save(@Validated(InsertValidationGroup.class)
                                   @RequestBody UserDTO userDTO){
        int save = userService.save(userDTO);
        if(save==1){
            return ResponseResult.success("新增成功！");
        }else{
            return ResponseResult.failure(ErrorCodeEnum.INSERT_ERROR);
        }
    }

    /**
     * 更新用户信息
     * PUT /api/users/{id} UserDTO
     * @return
     */
    @PutMapping("/{id}")
    @ApiOperation(
            value = "更新用户信息",
            notes = "备注说明信息",
            response = ResponseResult.class,
            httpMethod = "PUT"
    )
    @ApiImplicitParams({
            @ApiImplicitParam(
                    name="id",
                    value = "参数说明，用户主键",
                    required = true,
                    paramType = "path",
                    dataType = "Long",
                    example = "123123"
            ),
            @ApiImplicitParam(
                    name="userDTO",
                    value = "用户信息",
                    required = true,
                    paramType = "body",
                    dataType = "UserDTO",
                    dataTypeClass = UserDTO.class
            )
    })
    @ApiResponses({
            @ApiResponse(code=0000,message = "操作成功"),
            @ApiResponse(code=3004,message = "更新失败")
    })
    public ResponseResult update(@NotNull @PathVariable("id") Long id,
                                 @Validated(UpdateValidationGroup.class)
                                 @RequestBody UserDTO userDTO){
        int update = userService.update(id, userDTO);
        if(update==1){
            return ResponseResult.success("更新成功！");
        }else{
            return ResponseResult.failure(ErrorCodeEnum.UPDATE_ERROR);
        }
    }

    /**
     * 删除用户信息
     * DELETE /api/users/{id}
     * @return
     */
    @DeleteMapping("/{id}")
    public ResponseResult delete(@NotNull(message = "用户id不能为空")
                                     @PathVariable("id") Long id){
        int delete = userService.delete(id);
        if(delete==1){
            return ResponseResult.success("删除成功！");
        }else{
            return ResponseResult.failure(ErrorCodeEnum.DELETE_ERROR);
        }
    }

    /**
     * 查询用户信息
     * GET
     * @param pageNo
     * @param pageSize
     * @param query
     * @return
     */
    @Cacheable(cacheNames = "users-cache")
    @GetMapping
    public ResponseResult<PageResult> query(@NotNull Integer pageNo,
                                            @NotNull Integer pageSize,
                                            @Validated UserQueryDTO query){
        log.info("未使用缓存");
        // 构造查询条件
        PageQuery<UserQueryDTO> pageQuery = new PageQuery<>();
        pageQuery.setPageNo(pageNo);
        pageQuery.setPageSize(pageSize);
        pageQuery.setQuery(query);

        //查询
        PageResult<List<UserDTO>> pageResult = userService.query(pageQuery);
        //实体转换
        List<UserVO> userVOList = Optional.ofNullable(pageResult.getData())
                .map(List::stream)
                .orElseGet(Stream::empty)
                .map(userDTO -> {
                    UserVO userVO = new UserVO();
                    BeanUtils.copyProperties(userDTO, userVO);
                    userVO.setPassword("******");
                    userVO.setPhone(userDTO.getPhone().replaceAll("(\\d{3})\\d{4}(\\d4)", "$1***$3"));
                    return userVO;
                }).collect(Collectors.toList());
        // 封装返回结果
        PageResult<List<UserVO>> result = new PageResult<>();
        BeanUtils.copyProperties(pageResult, result);
        result.setData(userVOList);
        return ResponseResult.success(result);
    }

    @GetMapping("export")
    public ResponseResult<Boolean> export(@Valid UserQueryDTO query, @NotEmpty String filename){
        log.info("接受到处请求filename = {}", filename);
        //数据导出
       // excelExportService.export(query, filename);
        excelExportService.asyncExport(query, filename);
        return ResponseResult.success(Boolean.TRUE);
    }
}
